#include "warp.h"
#include "help_text.h"
#include "tag.h"
#include "enemy.h"
#include "weapon_choice.h"
#include "sounds.h"

enum help_frames {
	HF_WELCOME = 0,
	HF_STORY,
	HF_HIVE,
	HF_WASD,
	HF_WARP_INTRO,
	HF_WARP_REASON,
	HF_WARP_DETAIL,
	HF_WARP_BYE,
	
	HF_WEP_INTRO,
	HF_WEP_REASON,
	HF_WEP_HYPERSPACE,
	HF_WEP_CHOOSE,
	HF_WEP_DISMISS
	
};

void help_welcome() {
	make_help_text(HF_WELCOME);
}

void help_story() {
	make_help_text(HF_STORY);
}
void help_hive() {
	make_help_text(HF_HIVE);
}

void help_wasd() {
	make_help_text(HF_WASD);
}

void help_warp_intro() {
	warp_set(30);
	make_help_text(HF_WARP_INTRO);
}

void help_warp_reason() {
	make_help_text(HF_WARP_REASON);
}
void help_warp_detail() {
	make_help_text(HF_WARP_DETAIL);
}

void help_warp_bye() {
	make_help_text(HF_WARP_BYE);
}

void enemies_0_0() {
	make_satellite(vxy(100, 130), 1);
}

void enemies_0_1() {
	make_satellite(vxy(90,  130), 2);
	make_satellite(vxy(110, 130), 2);
}

void enemies_0_2() {
	make_satellite    (vxy(90,  130), 1);
	make_satellite    (vxy(110, 130), 1);
	make_satellite_off(vxy(100, 115), 3, 3);
}

void enemies_0_3() {
	make_basic_spray(vxy(100, 130), 4);
}

void enemies_0_4() {
	make_basic_spray(vxy(50,  130), 2);
	make_basic_spray(vxy(150, 130), 2);
	
}

void enemies_0_5() {
	make_basic_spray(vxy(100, 130), 5);
	make_satellite  (vxy( 90, 100), 1);
	make_satellite  (vxy(110, 100), 1);
	warp_set(58);
}

void enemies_1_0() {
	make_basic_spray(vxy(100, 130), 5);
	make_satellite(vxy(50, 80), 3);
	make_satellite(vxy(75, 90), 3);
	make_satellite(vxy(150, 80), 3);
	make_satellite(vxy(125, 90), 3);
}

void enemies_1_1() {
	make_basic_spray(vxy(100, 130), 5);
	
	make_basic_spray(vxy(50, 110), 5);
	make_basic_spray(vxy(150, 110), 5);
	
	make_basic_spray(vxy(75, 105), 5);
	make_basic_spray(vxy(125, 105), 5);
	
	make_satellite(vxy(25, 90), 3);
	make_satellite(vxy(175, 90), 3);
}

void enemies_1_2() {
	warp_set(30);
	make_satellite    (vxy( 40,  75), 2);
	make_satellite_off(vxy( 50,  80), 2, 3);
	make_satellite_off(vxy( 60,  85), 2, 6);
	make_satellite_off(vxy( 70,  90), 2, 9);
	make_satellite_off(vxy( 80,  95), 2, 12);
	make_satellite_off(vxy( 90, 105), 2, 15);
	make_satellite_off(vxy(100, 110), 2, 18);
	make_satellite_off(vxy(110, 115), 2, 21);
	make_satellite_off(vxy(120, 120), 2, 24);
	make_satellite_off(vxy(130, 125), 2, 27);
	make_satellite_off(vxy(140, 130), 2, 30);
	make_satellite_off(vxy(150, 135), 2, 33);
	make_satellite_off(vxy(160, 140), 2, 36);
}

void enemies_1_3() {
	warp_set(58);
	
	make_basic_spray(vxy(100, 80), 4);
	make_basic_spray(vxy(100, 100), 4);
	make_basic_spray(vxy(100, 120), 4);
}

void weapon_1_0() {
	make_weapon_choice(0);
}

void help_weapon_intro() {
	make_help_text(HF_WEP_INTRO);
}

void help_weapon_reason() {
	make_help_text(HF_WEP_REASON);
}

void help_weapon_hyperspace() {
	make_help_text(HF_WEP_HYPERSPACE);
}

void help_weapon_choose() {
	make_help_text(HF_WEP_CHOOSE);
}

void help_weapon_dismiss() {
	make_help_text(HF_WEP_DISMISS);
}

void weapon_2_0() {
	make_weapon_choice(0);
}

void weapon_2_1() {
	make_weapon_choice(0);
	make_weapon_choice(1);
}


void enemies_2_0() {
	make_triangle(vxy(100, 130), 8);
}

void enemies_2_1() {
	make_triangle(vxy(25, 140), 16);
	make_basic_spray(vxy(150, 120), 5);
	make_basic_spray(vxy(150, 140), 5);
}

void enemies_2_2() {
	warp_set(10.f);
	make_triangle(vxy(25, 140), 16);
	make_triangle(vxy(50, 130), 16);
	make_triangle(vxy(75, 120), 16);
	
	make_basic_spray(vxy(175, 130), 5);
	make_satellite(vxy(160, 110), 3);
	make_satellite(vxy(180, 110), 3);
}

void enemies_2_3() {
	warp_set(25.f);
	make_triangle(vxy(50, 100), 16);
	make_triangle(vxy(40, 80), 16);
	make_triangle(vxy(40, 120), 16);
	make_triangle(vxy(50, 140), 16);
	
	make_basic_spray(vxy(160, 130), 5);
	make_basic_spray(vxy(150, 120), 5);
	make_basic_spray(vxy(170, 120), 5);
}

void enemies_2_4() {
	warp_set(58.f);
	make_triangle(vxy(70, 100), 16);
	make_triangle(vxy(130, 100), 16);
	make_triangle(vxy(90, 90), 16);
	make_triangle(vxy(110, 90), 16);
	
	make_basic_spray(vxy(100, 130), 5);
	make_basic_spray(vxy(90, 140), 5);
	make_basic_spray(vxy(110, 130), 5);
}

void enemies_3_0() {
	make_triangle(vxy(25, 140), 6);
	make_triangle(vxy(25, 80), 6);
	make_triangle(vxy(175, 140), 6);
	make_triangle(vxy(175, 80), 6);
	make_basic_spray(vxy(100, 110), 5);
}

void enemies_3_1() {
	make_cycle(vxy(100, 120), 8);
}

void enemies_3_2() {
	make_triangle(vxy(130, 130), 12);
	make_cycle(vxy(120, 100), 12);
	make_cycle(vxy(140, 100), 12);
	make_basic_spray(vxy(50, 120), 5);
}

void enemies_3_3() {
	make_triangle(vxy(40, 130), 8);
	make_triangle(vxy(60, 130), 8);
	make_triangle(vxy(80, 130), 8);
	
	make_cycle(vxy(130, 100), 8);
	make_cycle(vxy(110, 100), 8);
	
	make_basic_spray(vxy(60, 140), 5);
}

void enemies_3_4() {
	warp_set(15.f);
	
	make_cycle(vxy(40, 120), 8);
	make_cycle(vxy(35, 105), 8);
	
	make_cycle(vxy(160, 120), 8);
	make_cycle(vxy(155, 105), 8);
	
	make_triangle(vxy(30, 130), 16);
	make_triangle(vxy(170, 130), 16);
}

void enemies_3_5() {
	warp_set(25.f);
	
	make_cycle(vxy(65, 95), 12);
	make_cycle(vxy(90, 110), 12);
	make_cycle(vxy(105, 125), 12);
	
	make_triangle(vxy(155, 120), 16);
	make_triangle(vxy(150, 100), 16);
	make_cycle(vxy(140, 80), 12);
}

void enemies_3_6() {
	warp_set(40.f);
	
	make_cycle(vxy(100, 130), 12);
	make_basic_spray(vxy(90, 110), 5);
	make_basic_spray(vxy(110, 110), 5);
	make_basic_spray(vxy(100, 90), 5);
	
	make_triangle(vxy(60, 120), 16);
	make_triangle(vxy(55, 100), 16);
	
	make_triangle(vxy(140, 120), 16);
	make_basic_spray(vxy(140, 140), 5);
}

void enemies_3_7() {
	warp_set(58.f);
	make_cycle(vxy(100, 130), 12);
	make_cycle(vxy(80, 130), 12);
	make_cycle(vxy(90, 135), 12);
	
	make_triangle(vxy(70, 100), 16);
	make_triangle(vxy(110, 100), 16);
}

void enemies_4_0() {
	make_triangle(vxy(100, 110), 10);
	make_triangle(vxy(85, 90), 10);
	make_triangle(vxy(115, 90), 10);
	make_cycle(vxy(100, 130), 12);
}

void enemies_4_2() {
	make_missile(vxy(140, 130), 10);
	make_missile(vxy(130, 110), 10);
	
	make_basic_spray(vxy(25, 140), 5);
	make_basic_spray(vxy(30, 140), 5);
	make_basic_spray(vxy(35, 140), 5);
}

void enemies_4_3() {
	make_missile(vxy(100, 130), 13);
	make_cycle(vxy(70, 120), 12);
	make_cycle(vxy(130, 120), 12);
	
	make_triangle(vxy(100, 140), 16);
}

void enemies_4_1() {
	make_missile(vxy(50, 120), 13);
	make_missile(vxy(100, 140), 13);
	make_missile(vxy(150, 120), 13);
}

void enemies_4_4() {
	warp_set(10.f);
	make_basic_spray(vxy(30, 80), 5);
	//make_basic_spray(vxy(35, 83), 5);
	make_basic_spray(vxy(40, 87), 5);
	//make_basic_spray(vxy(45, 92), 5);
	make_basic_spray(vxy(50, 98), 5);
	//make_basic_spray(vxy(60, 108), 5);
	make_basic_spray(vxy(70, 120), 5);
	//make_basic_spray(vxy(80, 130), 5);
	make_basic_spray(vxy(200-30, 80), 5);
	//make_basic_spray(vxy(200-35, 83), 5);
	make_basic_spray(vxy(200-40, 87), 5);
	//make_basic_spray(vxy(200-45, 92), 5);
	make_basic_spray(vxy(200-50, 98), 5);
	//make_basic_spray(vxy(200-60, 108), 5);
	make_basic_spray(vxy(200-70, 120), 5);
	//make_basic_spray(vxy(200-80, 130), 5);
	make_basic_spray(vxy(100, 95), 5);
}

void enemies_4_5() {
	warp_set(40.f);
	make_triangle(vxy(100.f, 100.f), 16);
	make_triangle(vxy(90.f, 105.f), 16);
	make_triangle(vxy(110.f, 105.f), 16);
	
	make_missile(vxy(100.f, 120.f), 13);
	make_missile(vxy(100.f, 140.f), 13);
	
	make_cycle(vxy(60.f, 120.f), 12);
	make_cycle(vxy(140.f, 120.f), 12);
	make_cycle(vxy(55.f, 110.f), 12);
	make_cycle(vxy(145.f, 110.f), 12);
}

void enemies_4_6() {
	warp_set(58.f);
	
	make_cycle(vxy(100.f, 120.f), 12);
	make_missile(vxy(100.f, 100.f), 13);
}

void enemies_4_demo() {
	make_triangle(vxy(100.f, 120.f), 16);
	make_triangle(vxy(50.f, 90.f), 16);
	make_triangle(vxy(150.f, 90.f), 16);
}

void weapon_missile() {
	make_weapon_choice(2);
}

void weapon_triple_cycle_missile() {
	make_weapon_choice(0);
	make_weapon_choice(1);
	make_weapon_choice(2);
}


size_t current_level = 0;
size_t current_group = 0;

typedef void (*enemy_group)(void);

enemy_group level_0[] = {
	&help_welcome,
	&help_story,
	&help_hive,
	&help_wasd,
	&enemies_0_0,
	&enemies_0_1,
	&enemies_0_2,
	&enemies_0_3,
	&help_warp_intro,
	&help_warp_reason,
	&help_warp_detail,
	&help_warp_bye,
	&enemies_0_4,
	&enemies_0_5
};

enemy_group level_1[] = {
	&help_weapon_intro,
	&help_weapon_reason,
	&help_weapon_hyperspace,
	&help_weapon_choose,
	&help_weapon_dismiss,
	&enemies_1_0,
	&weapon_1_0,
	&enemies_1_1,
	&enemies_1_2,
	&enemies_1_3
};

enemy_group level_2[] = {
	&enemies_2_0,
	&weapon_2_0,
	&enemies_2_1,
	&enemies_2_2,
	&weapon_2_1,
	&enemies_2_3,
	&enemies_2_4
};

enemy_group level_3[] = {
	&enemies_3_0,
	&enemies_3_1,
	&enemies_3_2,
	&weapon_2_0,
	&enemies_3_3,
	&enemies_3_4,
	&enemies_3_5,
	&enemies_3_6,
	&weapon_2_1,
	&enemies_3_7
};

enemy_group level_4[] = {
	&enemies_4_0,
	&enemies_4_1,
	&enemies_4_2,
	&weapon_2_0,
	&enemies_4_3,
	&weapon_missile,
	&enemies_4_demo,
	&weapon_triple_cycle_missile,
	&enemies_4_4,
	&enemies_4_5,
	&enemies_4_6
};

void enemies_5_0() {
	make_missile(vxy(50, 100), 13);
	make_missile(vxy(150, 100), 13);
	
	make_triangle(vxy(100, 120), 16);
	
	make_cycle(vxy(25, 90), 12);
	make_cycle(vxy(30, 90), 12);
	make_cycle(vxy(175, 90), 12);
	make_cycle(vxy(170, 90), 12);
}

void enemies_5_1() {
	make_mothership(vxy(0, 80));
}

enemy_group level_5[] = {
	&enemies_5_0,
	&enemies_5_1
};

enemy_group **levels;

#define LEVEL_COUNT 6

size_t level_size[] = {
	14,
	10,
	7,
	10,
	11,
	2
};

extern entity *player;
extern int player_do_warp_cycle;

void level_init() {
	levels = malloc(sizeof(enemy_group*) * LEVEL_COUNT);
	levels[0] = level_0;
	levels[1] = level_1;
	levels[2] = level_2;
	levels[3] = level_3;
	levels[4] = level_4;
	levels[5] = level_5;
}

int round_end = 0;
int waiting_on_input = 0;
int waiting_on_title = 1;

void level_load(size_t level) {
	current_level = level;
	current_group = 0;
	player->visible = 1;
	player->position = vxy(100, 20);
	player_do_warp_cycle = 0;
	warp_set(0);
	player_load_weapon(player, -1);
	player_reset(player);
	round_end = 0;
}

void level_lost() {
	for_ent(e, ent_all(tagged(TAG_ENEMY)), {
		ent_destroy(e);
	})
	
	for_ent(e, ent_all(tagged(TAG_BULLET)), {
		ent_destroy(e);
	})
	
	waiting_on_input = 1;
	player->visible = 0;
	make_you_lost();
}

void level_advance() {
	if(current_level >= LEVEL_COUNT) return;
	
	if(waiting_on_title) {
		entity *wait = ent_first(tagged(TAG_TITLE));
		if(!wait) {
			level_load(0);
			waiting_on_title = 0;
		}
		return;
	}
	
	if(waiting_on_input) {
		entity *wait = ent_first(tagged(TAG_YOU_LOST));
		if(!wait) {
			level_load(current_level);
			waiting_on_input = 0;
		}
		return;
	}
	
	size_t group_size = level_size[current_level];
	
	if(player_do_warp_cycle) {
		entity *cont = ent_first(tagged(TAG_CONTINUE));
		if(!cont) {
			level_load(current_level + 1);
		}
	}
	else {
		entity *enemy = ent_first(tagged(TAG_ENEMY));
		entity *help = ent_first(tagged(TAG_HELP_TEXT));
		entity *choice = ent_first(tagged(TAG_WEAPON_CHOICE));
		if(!enemy && !help && !choice) {
			if(current_group < group_size) levels[current_level][current_group]();
			else {
				player_do_warp_cycle = 1;
				round_end = 1;
				if(current_level == 5) {
					make_you_win();
				}
				else
					make_continue();
			}
			++current_group;
		}
	}
	
}